Skip to content

Fix idle pool cleaner generation race - #2289

Closed
pavel-ptashyts wants to merge 4 commits into
AsyncHttpClient:mainfrom
maygemdev:fix/channel-pool-idle-generation-race
Closed

Fix idle pool cleaner generation race#2289
pavel-ptashyts wants to merge 4 commits into
AsyncHttpClient:mainfrom
maygemdev:fix/channel-pool-idle-generation-race

Conversation

@pavel-ptashyts

Copy link
Copy Markdown
Contributor

Summary

  • claim the exact idle generation evaluated by the channel pool cleaner
  • keep generation and ownership in one atomic state without restoring per-offer allocations
  • cover stale close, fresh entry loss, and equal-timestamp generations with regression tests

Fixes #2284

Testing

  • ./mvnw -pl client -Dtest=DefaultChannelPoolTest test (19 tests passed)
  • full JDK 11 ./mvnw clean verify attempt: 1,326 tests passed and one unrelated timing assertion failed in SemaphoreTest.combinedCheckAcquireTime
  • immediate isolated SemaphoreTest rerun passed (10/10)

Codex on behalf of Pavel Ptashyts

Claim the exact idle generation evaluated by the cleaner so a lease and
re-offer cannot turn a stale expiry decision into a close of the fresh
entry.

Keep generation and ownership in one CAS-able state to preserve the
per-channel allocation model and avoid hiding a newer entry from poll.

Fixes AsyncHttpClient#2284

Codex on behalf of Pavel Ptashyts

Co-Authored-By: Codex <codex@openai.com>
Comment thread client/src/main/java/org/asynchttpclient/netty/channel/DefaultChannelPool.java Outdated
Comment thread client/src/main/java/org/asynchttpclient/netty/channel/DefaultChannelPool.java Outdated
Comment thread client/src/main/java/org/asynchttpclient/netty/channel/DefaultChannelPool.java Outdated
Make pool offers transfer an owned idle generation with CAS so duplicate
or concurrent offers cannot reset a leasable generation with a
non-atomic update.

Clarify generation encoding and snapshot claim naming, and exercise the
cleaner retention and close paths end to end.

Refs AsyncHttpClient#2284

Codex on behalf of Pavel Ptashyts

Co-Authored-By: Codex <codex@openai.com>
@pavel-ptashyts
pavel-ptashyts requested a review from hyperxpro July 25, 2026 18:34
Comment thread client/src/main/java/org/asynchttpclient/netty/channel/DefaultChannelPool.java Outdated
Comment thread client/src/main/java/org/asynchttpclient/netty/channel/DefaultChannelPool.java Outdated
Comment thread client/src/main/java/org/asynchttpclient/netty/channel/DefaultChannelPool.java Outdated
Comment thread client/src/main/java/org/asynchttpclient/netty/channel/DefaultChannelPool.java Outdated
Prevent duplicate or delayed offers from transferring a newer idle
generation. A reset-in-progress state now binds the timestamp update to
the exact owned snapshot without serializing reset calls.

Treat duplicate offers as accepted no-ops, defer partition creation until
a real insertion, and exercise the cleaner with a neighboring live entry.

Refs AsyncHttpClient#2284

Codex on behalf of Pavel Ptashyts

Co-Authored-By: Codex <codex@openai.com>
@pavel-ptashyts
pavel-ptashyts requested a review from hyperxpro July 26, 2026 08:37
@hyperxpro

Copy link
Copy Markdown
Member

This is going to be a lot of back and forth since this is a complicated - I will close and handle it.

@hyperxpro hyperxpro closed this Jul 27, 2026
@pavel-ptashyts
pavel-ptashyts deleted the fix/channel-pool-idle-generation-race branch July 27, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DefaultChannelPool cleaner can close a freshly re-offered channel

2 participants